package com.longteng.diamond.process;

import com.alibaba.fastjson.JSON;
import com.longteng.diamond.constant.ConstantType;
import com.longteng.diamond.domain.*;
import com.longteng.diamond.po.RequestResult;
import com.longteng.diamond.util.ReportLogFileUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator
 * DATE : 2018/7/18
 * TIME : 22:32
 * PROJECT : java-lesson
 * PACKAGE : com.longteng.lesson
 *
 * @author <a href="mailto:taki@qq.com">Administrator</a>
 */
@Slf4j
public class HttpProcesstor implements ClientProcesstor {

    public static OkHttpClient client = new OkHttpClient();

    private ReportLogFileUtil reportLogFileUtil;

    /**
     * 单个用例调用
     *
     * @param interfaceTest
     * @param requestResult
     * @param testCase
     * @return requestResult
     */
    @Override
    public void runTest(InterfaceTest interfaceTest, TestCase testCase, RequestResult requestResult) {
        Request request = this.buildRequest(interfaceTest, testCase);
        Response response = null;
        try {
            response = client.newCall(request).execute();
        } catch (Exception e) {
            requestResult.setSuccess(false);
            requestResult.setMsg("执行调用接口异常");
            log.error("执行调用接口异常,testCaseCase:" + testCase.getTestCaseName(), e);
            return;
        }
        String bodyStr = null;
        if (response.isSuccessful()) {
            log.info("response.code()==" + response.code());
            log.info("response.message()==" + response.message());
            try {
                bodyStr = response.body().string();
                requestResult.setSuccess(true);
                requestResult.setObj(bodyStr);
            } catch (Exception e) {
                requestResult.setSuccess(false);
                requestResult.setMsg("执行调用接口异常");
                log.error("获取body错误", e);
                return;
            }
            log.info("res==" + bodyStr);
        } else {
            requestResult.setMsg(response.message());
            requestResult.setCode(response.code());
            requestResult.setSuccess(false);
        }
    }

    /**
     * 构建一个request
     *
     * @param buildTestInterface
     * @param buildTestCase
     * @return Request
     */
    private Request buildRequest(InterfaceTest buildTestInterface, TestCase buildTestCase) {
        RequestBody requestBody = null;
        String paramType = buildTestCase.getParamType();
        String url = buildTestInterface.getInterfaceName();
        /**通过参数类型设置参数**/
        if (paramType.equalsIgnoreCase(ConstantType.KEYVALUE)) {
            String paramKeyValue = buildTestCase.getParamKeyValue();
            Map<String, String> map = JSON.parseObject(paramKeyValue, Map.class);
            String param = "";
            for (String key : map.keySet()) {
                param += key + "=" + map.get(key) + "&";
            }
            url = url + "?" + param;
        } else if (paramType.equalsIgnoreCase(ConstantType.BODY)) {
            String param = buildTestCase.getParamValue();
            MediaType mediaType=null;
            if(param.startsWith("<")){
                mediaType =MediaType.parse("application/xml; charset=utf-8");
            }else {
                mediaType =MediaType.parse("application/json; charset=utf-8");
            }
            requestBody = FormBody.create(mediaType, param);
        } else {

        }
        /**
         * 构建消息头
         * **/
        Headers.Builder builder = new Headers.Builder();
        String headerStr = buildTestInterface.getHeaders();
        if (!StringUtils.isBlank(headerStr)) {
           Map<String,String> map =JSON.parseObject(headerStr,Map.class);
           for(String key:map.keySet()){
               builder.add(key,map.get(key));
           }
        }
        Headers headers = builder.build();
        Request request = null;
        String interfaceMethod = buildTestInterface.getInterfaceMethod();
        if (ConstantType.GET.equalsIgnoreCase(interfaceMethod)) {
            request = new Request.Builder()
                    .url(url)
                    .get()
                    .headers(headers)
                    .build();
        } else {
            request = new Request.Builder()
                    .url(url)
                    .headers(headers)
                    .post(requestBody)
                    .build();
        }
        return request;
    }

    /**
     * 执行接口或者多个用例构建计划
     *
     * @param runTestContext
     * @return
     */
    @Override
    public void runTest(RunTestContext runTestContext) {
        reportLogFileUtil = runTestContext.getReportLogFileUtil();
        BuildTestCase buildTestCase = runTestContext.getBuildTestCase();
        BuildTestInterface buildTestInterface = runTestContext.getBuildTestInterface();
        reportLogFileUtil.write("初始化http request接口参数");
        Request request = this.buildRequest(buildTestInterface, buildTestCase);
        Response response = null;
        try {
            response = client.newCall(request).execute();
        } catch (Exception e) {
            log.error("执行调用接口异常,testCaseId:" + buildTestCase.getTestCaseId(), e);
            reportLogFileUtil.writeRedSpan("用例调用异常");
            reportLogFileUtil.writeRedSpan("异常信息:" + e.toString());
            return;
        }
        String bodyStr = null;
        if (response.isSuccessful()) {
            log.info("response.code()==" + response.code());
            log.info("response.message()==" + response.message());
            try {
                /**获取返回内容**/
                bodyStr = response.body().string();
                /**给测试用例设置实际结果**/
                buildTestCase.setActualResult(bodyStr);
            } catch (Exception e) {
                log.error("获取body错误", e);
                buildTestCase.setActualResult("获取body错误");
                return;
            }
            log.info("res==" + bodyStr);
        } else {
            try {
                buildTestCase.setActualResult(response.body().string());
            } catch (IOException i) {
                log.error("调用接口异常", i);
                reportLogFileUtil.writeRedSpan(i.getMessage());
            }
        }
    }
}
